generates a 16-bit pseudorandom number.
Games require a source of random numbers to keep the play surprising and exciting. Streams of pseudorandom bits can be used to generate white noise or interpolate between A/D converter measurements. Random simulates a hardware pseudorandom sequence generator made up of a shift register and three exclusive-OR (XOR) gates wired up as follows:
A circuit like this generates a sequence of bits that repeats every 65,535 shifts. Because of the long interval between the same bit pattern showing up, the sequence can, for many purposes, be considered random. To use Random, just call it. Upon return, the bits previously held in hiB and lowB will have been clocked through the equivalent of the circuit above. You can then use hiB or lowB, or the two combined into a 16-bit value, as your random number. You may also use a bit of one of the variables as a coin-toss decision maker. Random can be used to generate white-noise effects. Call the routine from within a tight program loop and copy one bit of hiB or lowB to an output pin. The stream of random bits at the output produces a rushing sound in a connected speaker or amplifier.
From one call to the next, the pattern inherent in Random is very apparent. A number is doubled, truncated to 16 bits (or 8, if you're using only one of the variables), and may or may not have a 1 added to the result. If Random is used to control patterns of lights or sounds, this pattern may be objectionable. In those cases, try to borrow an element of uncertainty from the outside world. For example, continuously call Random while waiting for the user to press a switch. This is analogous to BASIC programs on PCs that seed the random number generator with the current contents of the timer.
To see Random in operation, either run the program with the PSIM simulator, or connect the circuit below to an erasable PIC or PIC emulator, such as the Parallax downloader. Assemble and run RANDOM.SRC. The LEDs will show the sequence of pseudorandom patterns as they cycle through the variable lowB.
; ; *************************************************************************** ; *** Bubble Software Parallax to PIC Source Converter. Copyright 1999. *** ; *** http://www.bubblesoftonline.com email: sales@picnpoke.com *** ; *************************************************************************** ; ; RANDOM ; Generates a pseudorandom number. Works best if called from a loop so that ; the value of its workspace variable (consisting of lowB and hiB) is ; constantly stirred. P = pic16c55 #include <16c55.inc> ; processor assembler definitions _CONFIG _xt_osc & _wdt_off & _protect_off reset start org 8 hiB Res d'1' ; MSB of 16-bit random number. lowB Res d'1' ; LSB of 16-bit random number. temp Res d'1' ; Temporary counter for delay. temp2 Res d'1' ; Temporary counter for delay. ; Device data and reset vector org 0 start MovLW !rb,#0 ; Output to show sequ onence LEDs. MovWF !rb,w MOVLW d'13' ; Arbitrary starting values MOVWF lowB MOVLW d'99' ; for the shift register. MOVWF hiB start_loop CALL Random MOVF lowB,w ; Display 8-bit random numbers MOVWF 6h CALL delay ; on LEDs connected to RB. GOTO start_loop ; Endless loop ; Random number generator. Random MOVF hiB,w ; First, ensure that hiB and lowB aren't IORWF lowB,w ; all zeros. If they are, NOT hiB to FFh. BTFSC status,z ; Otherwise, leave hiB and lowB as is. COMF hiB MOVLW 0x80 ; We want to XOR hiB.7, hiB.6, hiB.4 BTFSC hiB,d'6' ; and lowB.3 together in W. Rather than XORWF hiB ; try to line up these bits, we just BTFSC hiB,d'4' ; check to see whether a bit is a 1. If it XORWF hiB ; is, XOR 80h into hiB. If it isn't, BTFSC lowB,d'3' ; do nothing. When we're done, the XORWF hiB ; XOR of the 4 bits will be in hiB.7. RLF hiB,w ; Move hiB.7 into carry. RLF lowB ; Rotate c into lowB.0, lowB.7 into c. RLF hiB ; Rotate c into hiB.0. RETLW 0h ; Delay loop for program demo. Remove when using just Random. delay DECFSZ temp GOTO delay DECFSZ temp2 GOTO delay RETLW 0h end
; RANDOM ; Generates a pseudorandom number. Works best if called from a loop so that ; the value of its workspace variable (consisting of lowB and hiB) is ; constantly stirred. device pic16c55,xt_osc,wdt_off,protect_off reset start org 8 hiB ds 1 ; MSB of 16-bit random number. lowB ds 1 ; LSB of 16-bit random number. temp ds 1 ; Temporary counter for delay. temp2 ds 1 ; Temporary counter for delay. ; Device data and reset vector org 0 start mov !rb,#0 ; Output to show sequence on LEDs. mov lowB,#13 ; Arbitrary starting values mov hiB,#99 ; for the shift register. :loop call Random mov rb,lowB ; Display 8-bit random numbers call delay ; on LEDs connected to RB. jmp :loop ; Endless loop ; Random number generator. Random mov w,hiB ; First, ensure that hiB and lowB aren't OR w,lowB ; all zeros. If they are, NOT hiB to FFh. snz ; Otherwise, leave hiB and lowB as is. NOT hiB mov w,#80h ; We want to XOR hiB.7, hiB.6, hiB.4 snb hiB.6 ; and lowB.3 together in W. Rather than XOR hiB,w ; try to line up these bits, we just snb hiB.4 ; check to see whether a bit is a 1. If it XOR hiB,w ; is, XOR 80h into hiB. If it isn't, snb lowB.3 ; do nothing. When we're done, the XOR hiB,w ; XOR of the 4 bits will be in hiB.7. mov w,<<hiB ; Move hiB.7 into carry. rl lowB ; Rotate c into lowB.0, lowB.7 into c. rl hiB ; Rotate c into hiB.0. ret ; Delay loop for program demo. Remove when using just Random. delay djnz temp,delay djnz temp2,delay ret
See also: